package it.tcm.TeacherClassMate.action;

import it.tcm.TeacherClassMate.beans.EquationBean;
import it.tcm.TeacherClassMate.beans.OrderMainBean;
import it.tcm.TeacherClassMate.beans.SessionUser;
import it.tcm.TeacherClassMate.facade.EquationManageBase;
import it.tcm.TeacherClassMate.facade.OrderMainManageBase;
import it.tcm.TeacherClassMate.form.GeneralForm;
import it.tcm.TeacherClassMate.form.TemplateForm;
import it.tcm.TeacherClassMate.persistent.DBConnection;
import it.tcm.TeacherClassMate.util.Util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBElement;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.Text;

public class MergeDataTemplateAction extends Action {

	// --------------------------------------------------------- Instance Variables

	// --------------------------------------------------------- Methods


	private Logger logger = Logger.getLogger(this.getClass().getName());
	private final String XPATH_TO_SELECT_TEXT_NODES = "//w:t";	
	
	/** 
	 * Method execute
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return ActionForward
	 * 
	 */

	@SuppressWarnings("rawtypes")
	public ActionForward execute(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response) 
	{		
		 logger.info("MERGE DATA TEMPLATE");
		 
		 String firstname = null;
		 String lastname = null;
		 SessionUser sessionUser = (SessionUser) request.getSession().getAttribute("sessionUser");
		 if (sessionUser != null) {
		     firstname = sessionUser.getFirstname();
		     lastname = sessionUser.getLastname();
		 }
		 
		 TemplateForm tform = (TemplateForm)form;
		 String idtemplate = tform.getIdtemplate();
		 String data = tform.getDate();
		 String classroom = tform.getClassroom();
		 String row = tform.getRow();
		 String istitute = tform.getIstitute();
		 if (data == null || data.equals("") ) {
			 request.setAttribute("warning_ins_temp", "NO_DATA");
	     	 return mapping.findForward("insertdatatemplate"); 
		 }
		 if (classroom == null || classroom.equals("") ) {
			 request.setAttribute("warning_ins_temp", "NO_CLASS");
	     	 return mapping.findForward("insertdatatemplate"); 
		 }
		 if (row == null || row.equals("") ) {
			 request.setAttribute("warning_ins_temp", "NO_ROW");
	     	 return mapping.findForward("insertdatatemplate"); 
		 }
		 // salvo i dati
		 OrderMainBean omb = new OrderMainBean();
		 omb.setClassroom(classroom);
		 omb.setVerificaDate(data);
		 omb.setIstitute(istitute);
		 omb.setVerificaRow(row);
		 omb.setTemplateId(Integer.valueOf(idtemplate));
		 OrderMainManageBase dao = new OrderMainManageBase();
		 if (sessionUser != null) {
			 omb.setUserId(sessionUser.getUserId());
		 }
		 dao.save(omb);
		 logger.debug("omb id = " + omb.getId());
		 logger.debug("idtemplate = " + idtemplate);
		 try {
		 
			 //carico il template
			 Context ctx = new InitialContext();
			 String docxFileDir = (String)ctx.lookup("java:comp/env/docxPath");
			 DBConnection db = new DBConnection();
			 Connection conn = db.getDBConnection();
			 Statement stmt = conn.createStatement();
			 ResultSet rs = stmt.executeQuery("select docx from TEMPLATE where id = " + idtemplate);
			 InputStream inputStreamTemplate = null;
			 Blob docxblob = null;
			 if (rs.next()) {
				  docxblob = rs.getBlob(1);
				  if (docxblob != null) {
					  inputStreamTemplate = docxblob.getBinaryStream();
				  } else {					  
					  //take it from file
					  File file = null;
					  file = new File(docxFileDir + "//template " + idtemplate + ".docx");
					  inputStreamTemplate = new FileInputStream(file);
				  }
			 } 
			 
			 Map<String,String> map = new HashMap<String,String>();
			 map.put("classroom", classroom);
			 //map.put("teacher", sessionUser.getFirstname() +  " " + sessionUser.getLastname());
			 map.put("teacher", firstname + " " + lastname);
			 map.put("date", data);
			 map.put("row", row);
			 map.put("istitutehastobelongatleastalotofcharacter",istitute);
				
			 WordprocessingMLPackage template = WordprocessingMLPackage.load(inputStreamTemplate);
			 inputStreamTemplate.close();
			 
			 List texts = getAllElementFromObject(template.getMainDocumentPart(), Text.class);
			 //List texts = template.getMainDocumentPart().getJAXBNodesViaXPath(XPATH_TO_SELECT_TEXT_NODES, false);
			 for (Object obj : texts) {
				//Text text = (Text) ((JAXBElement) obj).getValue();
				Text text = (Text)obj;
				String textValue = text.getValue();
				for (Object key : map.keySet()) {
					textValue = textValue.replaceAll(String.valueOf(key),(String) map.get(key));
				}
				text.setValue(textValue);
			 } 
			 File filedocx = new File(docxFileDir + "//temp.docx");
			 template.save(filedocx);
			 FileInputStream fisdocx = new FileInputStream(filedocx);
			 
			 String sql = "UPDATE ORDERMAIN SET docx = ? WHERE id = ?";
			 PreparedStatement stmt0 = conn.prepareStatement(sql);
			    
			 stmt0.setInt(2, omb.getId());
			 logger.info("filedocx.length()" + filedocx.length());	    		    	   
			 stmt0.setBinaryStream(1, fisdocx, (int) filedocx.length()); // metto il docx	
			 stmt0.execute();				    
			 fisdocx.close();
			 filedocx.delete();
			 conn.close();
			   
		 } catch(Exception e) {
			 logger.error("Exception e " + e.getMessage());
			 e.printStackTrace();
		 }
		 request.setAttribute(Util.FORM_GENERAL, new GeneralForm());
		 request.getSession().setAttribute(Util.ORDER_MAIN_OBJECT, omb);
		 EquationManageBase emb = new EquationManageBase();
		 List<EquationBean> equationBeanList = emb.getAll();
		 request.setAttribute("resultList", equationBeanList);
					 
		 return mapping.findForward("mergedatatemplate"); 
		 
	}
	
	
	private  List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
		List<Object> result = new ArrayList<Object>();
		if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
			logger.debug(obj.getClass().getName());
			if (obj.getClass().equals(toSearch))
				result.add(obj);
			else if (obj instanceof ContentAccessor) {
				List<?> children = ((ContentAccessor) obj).getContent();
			for (Object child : children) {
				result.addAll(getAllElementFromObject(child, toSearch));
			}	 
		}
		return result;
	}
	
	
}